#include "BlockQueue.hpp"
#include "Task.hpp"
#include <pthread.h>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>

// //1.没有task

// void *consumer(void *args)
// {
    
//     BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//     while(true)
//     {
//         int data = 0;
//         bq->Pop(&data);

//         std::cout << "consumer data:" << data << std::endl;
//         //注意消费者没有sleep

//     }
//     return nullptr;
// }

// void *productor(void *args)
// {
//     BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
//     while(true)
//     {
//         //1.有数据
//         int data = rand() % 10 + 1; // [1, 10]

//         //2.进行生产
//         bq->Push(data);
//         std::cout << "productor data: " << data << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// } 

// int main()
// {
//     srand((uint16_t)time(nullptr) ^ getpid() ^ pthread_self());//形成更随机的数
//     BlockQueue<int> *bq = new BlockQueue<int>();
//     pthread_t c, p;//消费者和生产者
//     pthread_create(&c, nullptr, consumer, bq);
//     pthread_create(&p, nullptr, productor, bq);

//     pthread_join(c, nullptr);
//     pthread_join(p, nullptr);
//     return 0;
// }


//2.有task
class ThreadData
{
public:
    BlockQueue<Task> *bq;
    std::string name;

};
void *consumer(void *args)
{
    
    ThreadData *td = (ThreadData*)args;
    while(true)
    {
        Task t;
        td->bq->Pop(&t);
        t();
        std::cout << "consumer data: " << t.PrintResult() << ", " << td->name << std::endl;
        //注意消费者没有sleep

    }
    return nullptr;
}

void *productor(void *args)
{
    //BlockQueue<int> *bq = static_cast<BlockQueue<int> *>(args);
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args); 
    while(true)
    {
        //1.有数据,从具体的场景中来，从网络中拿数据
        int data1 = rand() % 10; // [1, 10]//将来深刻理解生产消费，就要从这里入手，TODO
        usleep(rand()%123);
        int data2 = rand() % 10;
        usleep(rand() % 123);
        char oper = opers[rand() % (opers.size())];
        Task t(data1, data2, oper);
        std::cout << "productor task: " << t.PrintTask() << std::endl;


        //2.进行生产
        bq->Push(t);
        sleep(1);
    }
    return nullptr;
} 

int main()
{
    srand((uint16_t)time(nullptr) ^ getpid() ^ pthread_self());//形成更随机的数
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t c[3], p[2];//消费者和生产者

    ThreadData *td = new ThreadData();
    td->bq = bq;
    td->name = "thread-1";
    pthread_create(&c[0], nullptr, consumer, td);

    ThreadData *td1 = new ThreadData();
    td1->bq = bq;
    td1->name = "thread-2";
    pthread_create(&c[0], nullptr, consumer, td1);

    ThreadData *td2 = new ThreadData();
    td2->bq = bq;
    td2->name = "thread-3";
    pthread_create(&c[0], nullptr, consumer, td2);

    pthread_create(&p[0], nullptr, productor, bq);
    pthread_create(&p[1], nullptr, productor, bq);


    pthread_join(c[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(c[2], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(p[1], nullptr);
    return 0;
}